unit uUsbDriver;

interface

uses libusb, uBusMessage, uBusDriver;

type

  TUsbDriver = class (TBusDriver)
  private
    aUsbDevice: TLIBUSB;

    aVID,
    aPID,
    aReadEndpoint,
    aWriteEndpoint: Integer;

    aConected: boolean;

  public
    constructor Create(paVID, paPID, paReadEndpoint, paWriteEndpoint: Integer);

    function Connect: Boolean; override;
    function Disconnect: Boolean; override;
    function IsConnected: Boolean; override;

    function SendMessageAndGetAnswer(var paMessage: TBusMessage): Boolean; override;
  end;

implementation

{ TUsbDriver }

function TUsbDriver.Connect: Boolean;
begin
  result := false;

  if not aConected then
  begin
    //initialization
    USBdevInit(aUsbDevice);

    //set VID and PID to find device
    aUsbDevice.VID := aVID;
    aUsbDevice.PID := aPID;

    //Open device
    if not USBdevOpen(aUsbDevice) then
      exit;

    aConected := USBdevConfigure(aUsbDevice,1,0);
  end;

  result := aConected;
end;

constructor TUsbDriver.Create(paVID, paPID, paReadEndpoint, paWriteEndpoint: Integer);
begin
  aVID := paVID;
  aPID := paPID;
  aReadEndpoint := paReadEndpoint;
  aWriteEndpoint := paWriteEndpoint;
  aConected := false;
end;

function TUsbDriver.Disconnect: Boolean;
begin
  if aConected then
  begin
    USBdevClose(aUsbDevice);
    aConected := false;
  end;
  result := true;
end;

function TUsbDriver.IsConnected: Boolean;
begin
  result := aConected;
end;

function TUsbDriver.SendMessageAndGetAnswer(var paMessage: TBusMessage): Boolean;
var
  r: integer;
begin
  result := false;

  if aUsbDevice.handle = nil then
    exit;

  //send message
  r := usb_bulk_write(aUsbDevice.handle, aWriteEndpoint, @(paMessage.data), paMessage.length, USB_TIMEOUT);

  if r <> paMessage.length then
    exit;

  //receive answer
  usb_bulk_read(aUsbDevice.handle, aReadEndpoint, @(paMessage.data), paMessage.length, USB_TIMEOUT);

  result := true;
end;

end.
